package ossfile

import (
	"crypto/md5"
	"fmt"
	"git.mycaigou.com/gfyx/micro-gfyx-mp-api/infrastructure/vars"
	"git.myscrm.cn/golang/common/ykerrcode"
	"git.myscrm.cn/golang/stark/v4/config"
	aliyunoss "github.com/aliyun/aliyun-oss-go-sdk/oss"
	"math/rand"
	"mime/multipart"
	"path"
	"strconv"
	"time"
)

const (
	PUT_FILE_MAX_BYTES = 1024 * 1024 * 5
	SIGN_URL_EXPIRE = 3600*24 //oss文件url1天过期
)

var OssBuket *aliyunoss.Bucket
func NewOssBucket() (*aliyunoss.Bucket, error) {

	if vars.OssSetting == nil || vars.OssSetting.EndPoint == "" {
		err := config.MapConfig("OssSetting", vars.OssSetting, true)
		if err != nil {
			return nil, err
		}
		if vars.OssSetting == nil || vars.OssSetting.EndPoint == "" {
			return nil, ykerrcode.TogRPCError(ykerrcode.CONFIG_ERR, "OssSetting未配置")
		}
	}
	endpoint := vars.OssSetting.EndPoint
	accessKeyId := vars.OssSetting.AccessKeyId
	accessKeySecret := vars.OssSetting.AccessKeySecret
	client, err := aliyunoss.New(endpoint, accessKeyId, accessKeySecret)
	bucketName := vars.OssSetting.BucketName
	if err != nil {
		return nil, err
	}
	return client.Bucket(bucketName)
}

// 获取可访问的oss url
func GetSignURL(ossFilePath string) (string, error) {
	var err error
	if OssBuket == nil {
		OssBuket, err = NewOssBucket()
		if err != nil {
			return "", err
		}
	}
	// 获取文件url
	signedURL, err := OssBuket.SignURL(ossFilePath, aliyunoss.HTTPGet, SIGN_URL_EXPIRE)
	if err != nil {
		return "", err
	}
	return signedURL, nil
}

func PutOss(file *multipart.FileHeader, business string, isPrivate int64, tenantCode string) (ossFilePath string, signedURL string, err error) {
	// 目前只有私有的oss文件 isPrivate以后扩展用
	if isPrivate != 1 {
		return "", "", ykerrcode.TogRPCError(ykerrcode.INVALID_PARAMS, "目前只支持私有模式上传")
	}
	fileHandle, err := file.Open()
	if err != nil {
		return "","", err
	}
	defer fileHandle.Close()

	ossFilePath = AssemOssFilePath(file, business, tenantCode)
	bucket, err := NewOssBucket()
	if err != nil {
		return "", "", err
	}
	// 指定Object存储类型为低频访问。
	storageType := aliyunoss.ObjectStorageClass(aliyunoss.StorageStandard)
	// 指定Object访问权限为私有。
	objectAcl := aliyunoss.ObjectACL(aliyunoss.ACLPrivate)
	err = bucket.PutObject(ossFilePath, fileHandle, storageType, objectAcl)
	if err != nil {
		return "", "", err
	}

	// 获取文件url
	signedURL, err = bucket.SignURL(ossFilePath, aliyunoss.HTTPGet, SIGN_URL_EXPIRE)
	if err != nil {
		return "", "", err
	}
	return ossFilePath, signedURL, nil
}
func AssemOssFilePath(file *multipart.FileHeader, business string, tenantCode string) string {
	fileExt := path.Ext(file.Filename)
	// 此处重命名文件名 取此时的时间错的MD5为上传OSS的文件名
	data := []byte(time.Now().String())
	md5FileName := fmt.Sprintf("%x", md5.Sum(data))
	// 以年月为文件目录进行分类
	tTime := time.Now().Format("200601")
	// 年月/文件名.扩展名（注意不要再定义的目录前面加/）
	// ossFilePath = "/oppty/202306/234234234xfsdfsdf.xls"
	// 表示生成 [0,10000)之间的随机数
	randStr := strconv.Itoa(rand.Intn(10000))
	ossFilePath := ""
	if tenantCode != "" {
		ossFilePath = fmt.Sprintf("%s/%s/%s/%s%s", business, tenantCode, tTime, md5FileName+randStr, fileExt)
	} else {
		ossFilePath = fmt.Sprintf("%s/%s/%s%s", business, tTime, md5FileName+randStr, fileExt)
	}
	return ossFilePath
}


